package cn.cloud.all.security.oauth2.client.token;

import cn.cloud.all.security.crypto.codec.Base64;
import cn.cloud.all.security.oauth2.common.AuthenticationScheme;
import cn.cloud.all.security.oauth2.resource.OAuth2ProtectedResourceDetails;
import org.springframework.http.HttpHeaders;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;

import java.nio.charset.StandardCharsets;

public class DefaultClientAuthenticationHandler {

    public void authenticateTokenRequest(OAuth2ProtectedResourceDetails resource, MultiValueMap<String, String> form, HttpHeaders headers) {
        if (resource.isAuthenticationRequired()) {
            AuthenticationScheme scheme = AuthenticationScheme.header;
            if (resource.getClientAuthenticationScheme() != null) {
                scheme = resource.getClientAuthenticationScheme();
            }

            String clientSecret = resource.getClientSecret();
            clientSecret = clientSecret == null ? "" : clientSecret;
            switch (scheme) {
                case header:
                    form.remove("client_secret");
                    headers.add("Authorization", String.format("Basic %s", new String(Base64.encode(String.format("%s:%s", resource.getClientId(), clientSecret).getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8)));
                    break;
                case form:
                case query:
                    form.set("client_id", resource.getClientId());
                    if (StringUtils.hasText(clientSecret)) {
                        form.set("client_secret", clientSecret);
                    }
                    break;
                default:
                    throw new IllegalStateException("Default authentication handler doesn't know how to handle scheme: " + scheme);
            }
        }
    }
}
